package com.castle.fortress.admin.oa.service.impl;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.StrUtil;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.castle.fortress.admin.oa.dto.HolidayTypeDto;
import com.castle.fortress.admin.oa.entity.HolidayTypeEntity;
import com.castle.fortress.admin.oa.service.HolidayTypeService;
import com.castle.fortress.admin.system.entity.SysUser;
import com.castle.fortress.admin.system.service.SysUserService;
import com.castle.fortress.admin.utils.BizCommonUtil;
import com.castle.fortress.common.enums.YesNoEnum;
import com.castle.fortress.common.utils.ConvertUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.castle.fortress.admin.oa.entity.UserHolidaySettingEntity;
import com.castle.fortress.admin.oa.dto.UserHolidaySettingDto;
import com.castle.fortress.admin.oa.mapper.UserHolidaySettingMapper;
import com.castle.fortress.admin.oa.service.UserHolidaySettingService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Map;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 用户假期余额 服务实现类
 *
 * @author whc
 * @since 2022-11-03
 */
@Service
public class UserHolidaySettingServiceImpl extends ServiceImpl<UserHolidaySettingMapper, UserHolidaySettingEntity> implements UserHolidaySettingService {

    @Autowired
    private HolidayTypeService holidayTypeService;

    @Autowired
    private SysUserService service;

    /**
     * 获取查询条件
     *
     * @param userHolidaySettingDto
     * @return
     */
    public QueryWrapper<UserHolidaySettingEntity> getWrapper(UserHolidaySettingDto userHolidaySettingDto) {
        QueryWrapper<UserHolidaySettingEntity> wrapper = new QueryWrapper();
        if (userHolidaySettingDto != null) {
            UserHolidaySettingEntity userHolidaySettingEntity = ConvertUtil.transformObj(userHolidaySettingDto, UserHolidaySettingEntity.class);
            wrapper.eq(userHolidaySettingEntity.getUserId() != null, "user_id", userHolidaySettingEntity.getUserId());
            wrapper.eq(userHolidaySettingEntity.getHolidayTypeId() != null, "holiday_type_id", userHolidaySettingEntity.getHolidayTypeId());
        }
        return wrapper;
    }


    @Override
    public IPage<UserHolidaySettingDto> pageUserHolidaySetting(Page<UserHolidaySettingDto> page, UserHolidaySettingDto userHolidaySettingDto) {
        QueryWrapper<UserHolidaySettingEntity> wrapper = getWrapper(userHolidaySettingDto);
        Page<UserHolidaySettingEntity> pageEntity = new Page(page.getCurrent(), page.getSize());
        Page<UserHolidaySettingEntity> userHolidaySettingPage = baseMapper.selectPage(pageEntity, wrapper);
        Page<UserHolidaySettingDto> pageDto = new Page(userHolidaySettingPage.getCurrent(), userHolidaySettingPage.getSize(), userHolidaySettingPage.getTotal());
        pageDto.setRecords(ConvertUtil.transformObjList(userHolidaySettingPage.getRecords(), UserHolidaySettingDto.class));
        return pageDto;
    }

    @Override
    public IPage<UserHolidaySettingDto> pageUserHolidaySettingExtends(Page<UserHolidaySettingDto> page, UserHolidaySettingDto userHolidaySettingDto){
        Map<String,Long> pageMap = BizCommonUtil.getPageParam(page);
        UserHolidaySettingEntity userHolidaySettingEntity = ConvertUtil.transformObj(userHolidaySettingDto,UserHolidaySettingEntity.class);

        List<UserHolidaySettingEntity> userHolidaySettingEntityList=baseMapper.extendsList(pageMap,userHolidaySettingEntity);
        Long total = baseMapper.extendsCount(userHolidaySettingEntity);

        Page<UserHolidaySettingDto> pageDto = new Page(page.getCurrent(), page.getSize(),total);
        pageDto.setRecords(ConvertUtil.transformObjList(userHolidaySettingEntityList,UserHolidaySettingDto.class));
        return pageDto;
    }




    @Override
    public List<UserHolidaySettingDto> listUserHolidaySetting(UserHolidaySettingDto userHolidaySettingDto) {
        QueryWrapper<UserHolidaySettingEntity> wrapper = getWrapper(userHolidaySettingDto);
        List<UserHolidaySettingEntity> list = baseMapper.selectList(wrapper);
        return ConvertUtil.transformObjList(list, UserHolidaySettingDto.class);
    }

    @Override
    public List<UserHolidaySettingDto> listUserHolidaySettingExtends(UserHolidaySettingDto userHolidaySettingDto) {
        UserHolidaySettingEntity userHolidaySettingEntity = ConvertUtil.transformObj(userHolidaySettingDto, UserHolidaySettingEntity.class);
        List<UserHolidaySettingEntity> list = baseMapper.listExtends(userHolidaySettingEntity);
        return ConvertUtil.transformObjList(list, UserHolidaySettingDto.class);
    }

    @Async
    @Override
    @Transactional
    public void asyncGenerateUserSetting(Long userId, boolean isCover) {
        if (isCover) {
            //如果覆盖 直接删除原有
            remove(new QueryWrapper<UserHolidaySettingEntity>().eq("user_id", userId));
        }
        final List<HolidayTypeEntity> list = holidayTypeService.list();
        final ArrayList<UserHolidaySettingEntity> entities = new ArrayList<>();
        list.forEach(item -> {
            if (!isCover) {
                //不覆盖 每次要判断是否重复
                UserHolidaySettingEntity exists = getOne(new QueryWrapper<UserHolidaySettingEntity>().eq("user_id", userId).eq("holiday_type_id", item.getId()));
                if (exists != null) {
                    return;
                }
            }
            //判断是否存在
            final UserHolidaySettingEntity temp = new UserHolidaySettingEntity();
            temp.setUserId(userId);
            temp.setHolidayTypeId(item.getId());
            if (YesNoEnum.YES.getCode().equals(item.getIsLimit())) {
                temp.setTotalAmount(BigDecimal.valueOf(item.getAmount()));
                temp.setSurplusAmount(BigDecimal.valueOf(item.getAmount()));
            }
            entities.add(temp);
        });
        saveBatch(entities);
    }
    @Async
    @Override
    public void asyncUpdateUserSetting(HolidayTypeEntity holidayTypeEntity) {
        final UpdateWrapper<UserHolidaySettingEntity> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("holiday_type_id", holidayTypeEntity.getId());
        updateWrapper.set("total_amount", holidayTypeEntity.getAmount());
        updateWrapper.set("surplus_amount", holidayTypeEntity.getAmount());
        update(updateWrapper);
    }

    @Override
    public void asyncRemoveUserSetting(List<Long> ids) {
        final QueryWrapper<UserHolidaySettingEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("holiday_type_id", ids);
        remove(queryWrapper);
    }

    @Async
    @Override
    @Transactional
    public void asyncNewType(HolidayTypeEntity holidayTypeEntity) {
        final List<SysUser> users = service.list();
        final ArrayList<UserHolidaySettingEntity> entities = new ArrayList<>();
        users.forEach(item -> {
            final UserHolidaySettingEntity temp = new UserHolidaySettingEntity();
            temp.setUserId(item.getId());
            temp.setHolidayTypeId(holidayTypeEntity.getId());
            if (YesNoEnum.YES.getCode().equals(holidayTypeEntity.getIsLimit())) {
                temp.setTotalAmount(BigDecimal.valueOf(holidayTypeEntity.getAmount()));
                temp.setSurplusAmount(BigDecimal.valueOf(holidayTypeEntity.getAmount()));
            }
            entities.add(temp);
        });
        ListUtil.split(entities, 50).forEach(this::saveBatch);
    }
}

